<template>
    <div class="map-01">
        <div class="title">
            <h1>基础配置项,演示拥有的基础方法</h1>
        </div>
        <div id="custom-map"></div>
    </div>
</template>

<script>
let markerClusterer;
export default {
    data() {
        return {
            map: null,
            normal: L.layerGroup([L.tileLayer.chinaProvider("GaoDe.Normal.Map", {
                maxZoom: 18,
                minZoom: 3,
            })]),
            satellite: L.layerGroup([L.tileLayer.chinaProvider("GaoDe.Satellite.Map", {
                maxZoom: 18,
                minZoom: 3,
            }), L.tileLayer.chinaProvider("GaoDe.Satellite.Annotion", {
                maxZoom: 18,
                minZoom: 3,
            })]),
            type: 'satellite',
            baseOption: {
                editable: true,
                preferCanvas: false, // 是否使用 Canvas 来渲染 Path（路径）.默认情况下，所有 Path 都是使用 SVG 进行渲染。

                // 控件选项
                attributionControl: false, // 默认情况下，是否将 attribution 版权控件添加到地图中。
                zoomControl: false, // 默认情况下，是否将 zoom 缩放控件添加到地图中。

                // 交互选项
                closePopupOnClick: true, // 如果你不希望用户点击地图时 popups（弹出窗口）自动关闭，则可以将其设置为 false。
                zoomSnap: 1, // 强制让地图的缩放级别始终为这个值的倍数，特别是在 fitBounds() 或 pinch-zoom 后。默认情况下，缩放级别将是其最接近的整数； 较低的值（例如 0.5 or 0.1）允许更大的颗粒度。数值 0 意味着缩放级别将不会被 fitBounds 或 pinch-zoom。
                zoomDelta: 1, // 控件在进行 zoomIn()、 zoomOut() 以及按 + - 键或者使用 zoom 进行缩放之后，地图缩放级别改变的值。小于 1 的值（例如 0.5）允许更大的颗粒度。
                trackResize: true, // 地图是否会自动根据浏览器窗口的大小来更新自己。
                boxZoom: true, // 是否可以在按住 shift 键的同时拖动鼠标将地图缩放到指定的矩形区域。
                doubleClickZoom: true, // 地图是否可以通过双击来放大，以及在按住 shift 的同时双击来缩小。如果设置为 'center'，不管鼠标在哪里，双击缩放都将缩放到视图的中心。
                dragging: true, // 地图是否可以通过 mouse/touch 进行拖动。

                // 地图状态选项
                crs: Vue.L.CRS.EPSG3857, // 该地图使用的坐标系。如果你不确定坐标系这是什么意思，请不要更改它。
                center: [40.02404009136253, 116.50641060224784], // 地图初始化时的中心点位置
                zoom: 14, // 地图初始化时的缩放等级
                minZoom: 1, // 地图的最小缩放级别。 如果未指定，并且地图中至少有一个 GridLayer 或 TileLayer，则将使用其最低的 minZoom 选项。
                maxZoom: 17, // 地图的最大缩放级别。 如果未指定，并且地图中至少有一个 GridLayer 或 TileLayer，则将使用其最大的 maxZoom 选项。
                layers: [], // 默认添加到地图上的图层组
                maxBounds: null, // 当这个选项被设置后，地图将被限制在指定的地理边界内， 当用户平移将地图拖动到视图以外的范围时会出现弹回的效果， 并且也不允许缩小视图到指定范围以外的区域（这取决于地图的尺寸）. 要动态设置此限制，请使用 setMaxBounds 方法。
                // renderer: '*', // 在地图上绘制矢量图层的默认方法，默认为 L.SVG 或 L.Canvas， 这取决于浏览器是否支持。

                // 动画选项
                zoomAnimation: true, // 是否启用地图缩放动画。默认情况下，它在所有支持 CSS3 Transitions 的浏览器中都是启用的，Android 除外。
                zoomAnimationThreshold: 4, // 如果缩放差异超过此值，则不会为缩放设置动画。
                fadeAnimation: true, // 是否启用淡出淡出动画。默认情况下，它在所有支持 CSS3 Transitions 的浏览器中都是启用的，Android 除外。
                markerZoomAnimation: true, // Marker 标记是否使用缩放动画进行缩放。默认情况下，它在所有支持 CSS3 Transitions 的浏览器中都是启用的，Android 除外。
                transform3DLimit: 0, // 定义了 CSS 转换的最大尺寸。默认值不应该被改变，除非网页浏览器在做了一个大的 panBy 后将层定位在错误的地方。

                // Panning Inertia 选项
                inertia: true, // 如果启用，地图的平移会有一种惯性效应，即地图在拖动时形成动力，并在一段时间内继续向同一方向移动。在触摸设备上感觉特别好。除非在旧的 Android 设备上运行，否则默认情况下是启用的。
                inertiaDeceleration: 3000, // 惯性运动减速的速度, 以像素/秒²单位。
                inertiaMaxSpeed: Infinity, // 惯性运动的最大速度，以像素/秒为单位。
                easeLinearity: 0.2,
                worldCopyJump: false, // 启用该选项后，当你平移到世界的另一个 "copy" 时，地图会跟踪并无缝跳转到原来的副本，这样所有的覆盖物如 markers（标记）和 vector layers（矢量图层）都仍然可见。
                maxBoundsViscosity: 0.0, // 如果设置了 maxBounds，这个选项将控制拖动地图时边界的稳固程度。默认值为 0.0，允许用户以正常速度在界外拖动，更高的值会减慢地图在界外的拖动速度，而 1.0 使界外完全稳固，防止用户在界外拖动。

                // 按键导航选项
                keyboard: true, // 地图是否获得焦点，并且允许用户通过键盘和 +/- 来进行浏览地图。
                keyboardPanDelta: 80, // 按下方向键时，平移的像素数量。

                // 鼠标选项
                scrollWheelZoom: true, // 地图是否允许通过使用鼠标滚轮进行缩放。如果通过'center'，不管鼠标在哪里，都将会放大到视图的中心。
                wheelDebounceTime: 40, // 限制滚轮的触发速度（以毫秒为单位）。默认情况下，用户通过滚轮缩放的次数不能超过每 40 毫秒一次。
                wheelPxPerZoomLevel: 60, // 多少滚动像素（由 L.DomEvent.getWheelDelta 报告）意味着一个完整缩放级别的更改。 较小的值将使滚轮变焦更快（反之亦然）

                // 触摸交互选项
                tapHold: true, // 是否启用 mobile hacks 以支持 taps（在 iOS / Android上 修复 200ms 点击延迟）和 touch（触发 contextmenu 事件）。
                tapTolerance: 15, // 用户在触摸时，移动手指的像素数超过此值时被认为是有效的 tap。
                touchZoom: true, // 地图是否允许通过两根手指的触摸拖动进行缩放。如果通过 'center'，就会放大到视图的中心，而不管 touch 事件（手指）在哪里。除了老式的 Android 系统外，对具有 touch-capable 功能的网络浏览器来说是启用的。
                bounceAtZoomLimits: true, // 如果您不希望在地图缩放超过最小/最大缩放范围时反弹，请将其设置为 false。

                removeOutsideVisibleBounds: true
            },

        }
    },
    methods: {
        /**
         * @Description 返回 Renderer 的实例，该实例应该用于渲染给定的 Path。它将确保地图和路径的 Renderer 选项得到尊重，并且 Renderer 确实存在于地图上
        */
        getRenderer(e) {
            console.log(e);
        },

        // 图层和控件
        /**
         * @Description 添加控件到地图上
        */
        addControl(e) {
            this.map.addControl()
        },
        /**
         * @Description 从地图上移除一个指定的控件
        */
        removeControl(e) {
            this.map.removeControl()
        },
        /**
         * @Description 添加图层到地图上
        */
        addLayer(e) {
            if (this.type === 'normal') {
                this.map.addLayer(this.satellite);
                this.type = 'satellite';
            } else {
                this.map.addLayer(this.normal);
                this.type = 'normal';
            }
        },
        /**
         * @Description 从地图上移除一个指定的图层
        */
        removeLayer(e) {
            if (this.type === 'normal') {
                this.map.removeLayer(this.normal);
            } else {
                this.map.removeLayer(this.satellite);
            }
        },
        /**
         * @Description 地图上是否存在指定的图层，如果给定的图层当前已被加到地图上，则返回 true
        */
        hasLayer(e) {
            console.log(this.map.hasLayer(this.satellite));
        },
        /**
         * @Description 遍历地图的图层，选择指定上下文的迭代器函数。
        */
        eachLayer() {
            this.map.eachLayer(function (layer) {
                layer.bindPopup('Hello');
            });
        },
        /**
         * @Description 打开指定的 Popup（弹窗）。（如果之前有打开其他的，会自动关闭，确保只有一个）
        */
        openPopup() {
            L.popup().setLatLng(this.baseOption.center).setContent('<p>Hello world!<br />This is a nice popup.</p>').openPopup(this.map);
        },
        /**
         * @Description 关闭之前打开的（或给定某个）Popup （弹窗）。
        */
        closePopup() {
            L.popup().setLatLng(this.baseOption.center).setContent('<p>Hello world!<br />This is a nice popup.</p>').openPopup(this.map);
        },

        qwaqweqwe() {
            //删除原来的标注
            markerClusterer && markerClusterer.clearLayers && markerClusterer.clearLayers()

            // 初始化点聚合
            markerClusterer = L.markerClusterGroup({
                spiderfyOnMaxZoom: false,
                showCoverageOnHover: false,
                zoomToBoundsOnClick: true
            })

            // 聚合点点击事件，点击展开点
            markerClusterer.on('clusterclick', function (e) {
                e.layer.zoomToBounds()
            })
        },

        dian() {
            let point = L.marker(this.baseOption.center,);
            point.on('click', e => {
                console.log(e);
                let asd = L.popup({ minWidth: 100 })
                    .setLatLng([e.latlng.lat, e.latlng.lng])
                    .openOn(this.map)
                setTimeout(() => {
                    asd.setContent(() => {
                        var container = L.DomUtil.create("div");
                        container.innerHTML = '123123';
                        container.style.width = '300px';
                        container.style.height = '300px';
                        let chart = this.$echarts.init(container);
                        chart.setOption({
                            xAxis: {
                                type: 'category',
                                data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
                            },
                            yAxis: {
                                type: 'value'
                            },
                            series: [
                                {
                                    data: [150, 230, 224, 218, 135, 147, 260],
                                    type: 'line'
                                }
                            ]
                        });
                        return container
                    })
                }, 0);
            });
            let point1 = L.marker([41.02404009136253, 117.50641060224784]);
            point1.on('click', e => {
                console.log(e);
                let asd = L.popup({ minWidth: 100 })
                    .setLatLng([e.latlng.lat, e.latlng.lng])
                    .openOn(this.map)
                setTimeout(() => {
                    asd.setContent(() => {
                        var container = L.DomUtil.create("div");
                        container.innerHTML = '123123';
                        container.style.width = '300px';
                        container.style.height = '300px';
                        let chart = this.$echarts.init(container);
                        chart.setOption({
                            xAxis: {
                                type: 'category',
                                data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
                            },
                            yAxis: {
                                type: 'value'
                            },
                            series: [
                                {
                                    data: [150, 230, 224, 218, 135, 147, 260],
                                    type: 'line'
                                }
                            ]
                        });
                        return container
                    })
                }, 0);
            })

            // 把点添加到 markerClusterer 
            markerClusterer.addLayer(point).addLayer(point1);
            // 把 markerClusterer 添加到 map 中
            markerClusterer.addTo(this.map)
        },

        /**
         * @Description 初始化生成地图
        */
        initCreateMap() {
            this.map = Vue.L.map("custom-map", this.baseOption);
            for (const key in this.eventOption) {
                this.map.on(key, this.eventOption[key])
            }
        }

    },
    mounted() {
        this.initCreateMap();
        this.addLayer();
        setTimeout(() => {
            // this.removeLayer();
            // this.addLayer();
            // this.hasLayer();
            // this.openPopup();
        }, 3000);

        // 添加图片
        var imageUrl = 'https://maps.lib.utexas.edu/maps/historical/newark_nj_1922.jpg',
            imageBounds = [[10, -108], [1, -88]];
        L.imageOverlay(imageUrl, imageBounds).addTo(this.map);
        // 添加视频
        var videoUrl = 'https://www.mapbox.com/bites/00188/patricia_nasa.webm',
            videoBounds = [[32, -130], [13, -100]];
        L.videoOverlay(videoUrl, videoBounds).addTo(this.map);
        // 添加SVG
        var svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg");
        svgElement.setAttribute('xmlns', "http://www.w3.org/2000/svg");
        svgElement.setAttribute('viewBox', "0 0 200 200");
        svgElement.innerHTML = '<rect width="200" height="200"/><rect x="75" y="23" width="50" height="50" style="fill:red"/><rect x="75" y="123" width="50" height="50" style="fill:#0013ff"/>';
        var svgElementBounds = [[32, -130], [13, -100]];
        L.svgOverlay(svgElement, svgElementBounds).addTo(this.map);
        // 添加折现
        var latlngs = [
            [[45.51, -122.68],
            [37.77, -122.43],
            [34.04, -118.2]],
            [[40.78, -73.91],
            [41.83, -87.62],
            [32.76, -96.72]]
        ];
        var polyline = L.polyline(latlngs, { color: 'red' }).addTo(this.map);
        // 添加多边形
        var latlngs = [
            [ // first polygon
                [[37, -109.05], [41, -109.03], [41, -102.05], [37, -102.04]], // outer ring
                [[37.29, -108.58], [40.71, -108.58], [40.71, -102.50], [37.29, -102.50]] // hole
            ],
            [ // second polygon
                [[41, -111.03], [45, -111.04], [45, -104.05], [41, -104.05]]
            ]
        ];
        var polygon = L.polygon(latlngs, { color: 'red' }).addTo(this.map);
        // 添加矩形
        var bounds = [[54.559322, -5.767822], [56.1210604, -3.021240]];
        var rectangle = L.rectangle(bounds, { color: "#ff7800", weight: 1 }).addTo(this.map);
        // 添加圆形
        var circle = L.circle([50.5, 30.5], { radius: 200 });

        setTimeout(() => {
            // circle.editing.enable();
            circle.enableEdit()
            circle.addTo(this.map);
            this.map.fitBounds(circle.getBounds());
            circle.on('edit', (e) => {
                console.log(e.target);
                let radius = e.target._mRadius
            });
        }, 1000)

        L.control.scale().addTo(this.map);


        L.BaseLayersControl = L.Control.extend({
            options: {
                position: "bottomright",
            },
            onAdd: (map) => {
                var container = L.DomUtil.create("div", "leaflet-control leaflet-bar"),
                    link = L.DomUtil.create("a", "", container);

                link.href = "#";
                let normalEl =
                    '<i class="iconfont icon-nwp-weixing" style="font-size: 20px;"></i>',
                    satEl =
                        '<i class="iconfont icon-nwp-weixing" style="color: var(--theme-color);font-size: 20px;"></i>',
                    isNormal = true;
                link.innerHTML = 'normalEl';
                L.DomEvent.on(link, "click", L.DomEvent.stop).on(
                    link,
                    "click",
                    () => {
                        isNormal = !isNormal;
                        link.innerHTML = isNormal ? 'normalEl' : 'satEl';
                        if (isNormal) {
                            this.map.removeLayer(this.satellite);
                            this.map.addLayer(this.normal);
                        } else {
                            this.map.removeLayer(this.normal);
                            this.map.addLayer(this.satellite);
                        }
                    }
                );
                return container;
            },
        });
        this.map.addControl(new L.BaseLayersControl());
        L.BaseLayersControls = L.Control.extend({
            options: {
                position: "bottomright",
            },
            onAdd: (map) => {
                var container = L.DomUtil.create("div", "leaflet-control leaflet-bar"),
                    link = L.DomUtil.create("a", "", container);

                link.href = "#";
                link
                let normalEl =
                    '<i class="iconfont icon-nwp-weixing" style="font-size: 20px;"></i>',
                    satEl =
                        '<i class="iconfont icon-nwp-weixing" style="color: var(--theme-color);font-size: 20px;"></i>',
                    isNormal = true;
                link.innerHTML = 'normalEl';
                L.DomEvent.on(link, "click", L.DomEvent.stop).on(
                    link,
                    "click",
                    () => {
                        isNormal = !isNormal;
                        link.innerHTML = isNormal ? 'normalEl' : 'satEl';
                        if (isNormal) {
                            this.map.removeLayer(this.satellite);
                            this.map.addLayer(this.normal);
                        } else {
                            this.map.removeLayer(this.normal);
                            this.map.addLayer(this.satellite);
                        }
                    }
                );
                return container;
            },
        });
        this.map.addControl(new L.BaseLayersControls());
        this.qwaqweqwe();
        this.dian();
        return
        let arr = [[37, -109.05], [41, -109.03], [41, -102.05], [37, -102.04]];
        var polygon = L.polygon(arr, { color: 'red' }).addTo(this.map);
        let marker = L.marker(this.baseOption.center, { draggable: true }).addTo(this.map);


        marker.bindPopup(() => {
            return '<h1>123</h1>'
        });
        marker.bindTooltip(() => {
            return '<h1>123</h1>'
        });
        marker.on('click', (option) => {
            console.log(option);
        })
        marker.on('contextmenu', (option) => {
            console.log(option);
        })
        let marker1 = L.marker([41.02404009136253, 117.50641060224784]).addTo(this.map);
        console.log(marker);
    }
}
</script>

<style lang="scss" scoped>
.map-01 {
    width: 100%;
    height: 100%;
    padding: 20px 0;
    box-sizing: border-box;
    position: relative;

    .title {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 80px;
        background: rgba($color: #000000, $alpha: 0.2);
        z-index: 999;
        display: flex;
        align-items: center;
        justify-content: center;
    }

    #custom-map {
        width: 100%;
        height: 100%;
    }
}
</style>